/**
 * 获取jsapi_ticket
 *      是什么？jsapi_ticket是公众号用于调用微信JS接口的临时票据
 *      特点：唯一的，有效期为2小时，调用次数非常有限
 *
 * 请求地址：（get请求）
 *  https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=ACCESS_TOKEN&type=jsapi
 *
 * 设计思路
 *  1.首次本地没有，发送请求获取jsapi_ticket，保存下来（本地文件）
 *  2.第二次或以后：先去本地读取文件，判读是否过期（过期：重新获取，并保存；没过期：直接使用）
 *
 *  request-promise-native，返回值是一个promise对象
 *
 */
const rpn = require('request-promise-native');
const {writeFile, readFile} = require('fs');
const {fetchAccessToken} = require('./accessToken');
const {jsapi_ticket_api} = require('../config/api');


// 获取jsapiTicket
const getJsapiTicket = () => {
    return new Promise(async (resolve, reject) => {
        const data = await fetchAccessToken();
        const url = `${jsapi_ticket_api}&access_token=${data.access_token}`;
        rpn({method: 'GET', url, json: true})
            .then(res => {
                resolve({
                    ticket: res.ticket,
                    expires_in: Date.now() + (res.expires_in - 300) * 1000
                });
            })
            .catch(err => {
                reject('出错了' + err);
            });

    })
};
// 保存jsapiTicket
const saveJsapiTicket = (data) => {
    return new Promise((resolve, reject) => {
        writeFile('./jsapiTicket.txt', JSON.stringify(data), err => {
            if (!err) {
                console.log("文件保存成功...");
                resolve();
            } else {
                reject('saveJsapiTicket出错：' + err);
            }
        });
    });
};
// 读取jsapiTicket
const readJsapiTicket = () => {
    return new Promise((resolve, reject) => {
        readFile('./jsapiTicket.txt', (err, data) => {
            if (!err) {
                console.log("文件读取成功...");
                resolve(JSON.parse(data));
            } else {
                reject('readJsapiTicket出错：' + err);
            }
        });
    });
};
// 判断jsapiTicket是否有效
const isValidJsapiTicket = (data) => {
    if (!data && !data.ticket && !data.expires_in) {
        return false;
    }
    if (data.expires_in < Date.now()) {
        return false;
    }
    return true;
};

module.exports = {
    // 获取有效的jsapiTicket
    fetchJsapiTicket() {
        if (this.ticket && this.expires_in && isValidJsapiTicket(this)) {
            return Promise.resolve({
                ticket: this.ticket,
                expires_in: this.expires_in
            });
        }
        return readJsapiTicket()
            .then(async res => {
                if (isValidJsapiTicket(res)) {
                    return Promise.resolve(res);
                } else {
                    const res = await getJsapiTicket();
                    await saveJsapiTicket(res);
                    return Promise.resolve(res);
                }
            })
            .catch(async err => {
                const res = await getJsapiTicket();
                await saveJsapiTicket(res);
                return Promise.resolve(res);
            })
            .then(res => {
                this.ticket = res.ticket;
                this.expires_in = res.expires_in;
                return Promise.resolve(res);
            })
    }

}

